Current File : /home/jeconsul/public_html/wp-content/plugins/siteseo/main/generatesitemap.php |
<?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class GenerateSitemap{
private static $paged = 1;
static function settings(){
global $siteseo;
if(empty($siteseo->setting_enabled['toggle-xml-sitemap'])){
return;
}
if(!empty($siteseo->sitemap_settings['xml_sitemap_html_enable'])){
add_shortcode('siteseo_html_sitemap', '\SiteSEO\GenerateSitemap::html_sitemap');
}
if(!empty($siteseo->sitemap_settings['xml_sitemap_general_enable'])){
self::xml_sitemap();
}
}
static function xml_sitemap(){
add_filter('query_vars', function($vars){
$vars[] = 'sitemap_type';
$vars[] = 'paged';
$vars[] = 'sitemap-stylesheet';
return $vars;
});
}
static function add_rewrite_rules(){
global $siteseo;
add_rewrite_rule('^sitemaps\.xsl$', 'index.php?sitemap-stylesheet=sitemap', 'top');
add_rewrite_rule('^sitemaps\.xml$', 'index.php?sitemap_type=general', 'top');
add_rewrite_rule('^author.xml$', 'index.php?sitemap_type=author', 'top');
add_rewrite_rule('^media-sitemap([0-9]+)?.xml$', 'index.php?sitemap_type=media&paged=$matches[1]', 'top');
add_rewrite_rule('^news([0-9]+)?.xml$', 'index.php?sitemap_type=news&paged=$matches[1]', 'top');
add_rewrite_rule('^video-sitemap([0-9]+)?.xml$', 'index.php?sitemap_type=video&paged=$matches[1]', 'top');
if(isset($siteseo->sitemap_settings['xml_sitemap_post_types_list'])){
foreach($siteseo->sitemap_settings['xml_sitemap_post_types_list'] as $post_type => $settings){
if(!empty($settings['include'])){
add_rewrite_rule('^'.$post_type.'-sitemap([0-9]+)?\.xml$', 'index.php?sitemap_type='.$post_type.'&paged=$matches[1]', 'top');
}
}
}
if(isset($siteseo->sitemap_settings['xml_sitemap_taxonomies_list'])){
foreach($siteseo->sitemap_settings['xml_sitemap_taxonomies_list'] as $taxonomy => $settings){
if(!empty($settings['include'])){
add_rewrite_rule('^'.$taxonomy.'-sitemap([0-9]+)?\.xml$', 'index.php?sitemap_type='.$taxonomy.'&paged=$matches[1]', 'top');
}
}
}
flush_rewrite_rules();
}
static function handle_sitemap_requests(){
global $siteseo;
$pro_settings = isset($siteseo->pro) ? $siteseo->pro : '';
self::maybe_redirect();
// Output the Sitemap style
if(get_query_var('sitemap-stylesheet')){
self::sitemap_xsl();
exit;
}
if(get_query_var('paged')){
self::$paged = get_query_var('paged');
}
$type = get_query_var('sitemap_type');
if(!empty($type)){
if($type === 'news' && !empty($pro_settings['google_news']) && !empty($pro_settings['toggle_state_google_news'])){
self::generate_google_news_sitemap();
exit;
}
if($type === 'video' && !empty($pro_settings['toggle_state_video_sitemap']) && !empty($pro_settings['enable_video_sitemap'])){
self::generate_video_sitemap();
exit;
}
// Custom post type
if(isset($siteseo->sitemap_settings['xml_sitemap_post_types_list'][$type]) && !empty($siteseo->sitemap_settings['xml_sitemap_post_types_list'][$type]['include'])){
self::generateSitemap($type);
exit;
}
//custom taxomies type
if(isset($siteseo->sitemap_settings['xml_sitemap_taxonomies_list'][$type]) && !empty($siteseo->sitemap_settings['xml_sitemap_taxonomies_list'][$type]['include'])){
self::generate_term_sitemap($type);
exit;
}
switch($type){
case 'general':
self::generate_index_sitemap();
break;
case 'post':
self::generateSitemap('post');
break;
case 'page':
self::generateSitemap('page');
break;
case 'category':
self::generate_term_sitemap('category');
break;
case 'post_tag':
self::generate_term_sitemap('post_tag');
break;
case 'author':
self::generate_author_sitemap();
break;
case 'media':
self::generate_media_sitemap();
break;
case 'news':
self::generate_google_news_sitemap();
break;
case 'video':
self::generate_video_sitemap();
break;
default:
wp_die(esc_html__('Invalid sitemap type.', 'siteseo'));
}
}
}
static function generate_index_sitemap(){
global $siteseo;
$pro_settings = isset($siteseo->pro) ? $siteseo->pro : '';
header('Content-Type: application/xml; charset=UTF-8');
if(get_option('permalink_structure')){
$xsl_url = home_url('/sitemaps.xsl');
} else {
$xsl_url = home_url('/?sitemaps-stylesheet=sitemap');
}
echo '<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="' . esc_url($xsl_url) . '" ?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
if(isset($siteseo->sitemap_settings['xml_sitemap_post_types_list'])){
foreach($siteseo->sitemap_settings['xml_sitemap_post_types_list'] as $post_type => $settings){
$posts = get_posts(
[
'post_type' => $post_type,
'fields'=> 'ids',
'numberposts' => -1,
'post_status' => 'publish',
'has_password' => false,
'no_found_rows' => true,
'ignore_sticky_posts' => true,
'update_post_term_cache' => false,
]
);
if(empty($posts)){
continue;
}
$total_pages = (int) ceil(count($posts) / 1000);
if(!empty($settings['include']) && !empty($total_pages)){
for($page = 1; $page <= $total_pages; $page++){
echo '<sitemap>
<loc>'.esc_url(home_url("/$post_type-sitemap$page.xml")).'</loc>
</sitemap>';
}
}
}
}
// Taxonomies
if(isset($siteseo->sitemap_settings['xml_sitemap_taxonomies_list'])){
foreach($siteseo->sitemap_settings['xml_sitemap_taxonomies_list'] as $taxonomy => $settings){
$tax_count = wp_count_terms([
'hide_empty' => true,
'hierarchical' => false,
'update_term_meta_cache' => false,
]);
if(empty($tax_count)){
return;
}
$total_pages = (int) ceil($tax_count/2000);
if(!empty($settings['include'])){
for($page = 1; $page <= $total_pages; $page++){
echo '<sitemap>
<loc>'.esc_url(home_url("/$taxonomy-sitemap$page.xml")).'</loc>
</sitemap>';
}
}
}
}
// Author
if(!empty($siteseo->sitemap_settings['xml_sitemap_author_enable'])){
echo '<sitemap>
<loc>'.esc_url(home_url('/author.xml')).'</loc>
</sitemap>';
}
if(!empty($pro_settings['google_news']) && !empty($pro_settings['toggle_state_google_news'])){
echo '<sitemap>
<loc>'.esc_url(home_url('/news.xml')).'</loc>
</sitemap>';
}
if(!empty($pro_settings['toggle_state_video_sitemap']) && !empty($pro_settings['enable_video_sitemap'])){
$video_posts = get_posts([
'post_type' => 'any',
'fields' => 'ids',
'numberposts' => -1,
'meta_query' => [
[
'key' => '_siteseo_video_disabled',
'compare' => 'NOT EXISTS'
]
]
]);
if(!empty($video_posts)){
$total_pages = (int) ceil(count($video_posts) / 1000);
for($page = 1; $page <= $total_pages; $page++){
echo '<sitemap>
<loc>'.esc_url(home_url("/video-sitemap$page.xml")).'</loc>
</sitemap>';
}
}
}
echo '</sitemapindex>';
exit;
}
// post
static function generate_post_sitemap(){
self::generateSitemap('post');
}
// page
static function generate_page_sitemap(){
self::generateSitemap('page');
}
// category
static function generate_category_sitemap(){
self::generate_term_sitemap('category');
}
//post tag
static function generate_post_tag_sitemap(){
self::generate_term_sitemap('post_tag');
}
// taxonomy
static function generate_taxonomy_sitemap(){
self::generate_term_sitemap('taxonomy');
}
// google news pro feature
static function generate_google_news_sitemap(){
if(class_exists('\SiteSEOPro\GoogleNews') && method_exists('\SiteSEOPro\GoogleNews', 'google_news_sitemap')){
\SiteSEOPro\GoogleNews::google_news_sitemap();
}
}
// video sitemap pro feature
static function generate_video_sitemap(){
if(class_exists('\SiteSEOPro\VideoSitemap') && method_exists('\SiteSEOPro\VideoSitemap', 'render_sitemap')){
\SiteSEOPro\VideoSitemap::render_sitemap();
}
}
static function generateSitemap($post_type){
global $siteseo;
header('Content-Type: application/xml; charset=utf-8');
$offset = (1000*(self::$paged - 1));
$posts = get_posts(
[
'post_type' => $post_type,
'post_status' => 'publish',
'numberposts' => 1000,
'offset' => $offset,
'order' => 'DESC',
'orderby' => 'modified',
'has_password' => false,
'no_found_rows' => true,
'meta_query' => [
[
'key' => '_siteseo_robots_index',
'compare' => 'NOT EXISTS'
]]
]);
if(get_option('permalink_structure')){
$xsl_url = home_url('/sitemaps.xsl');
} else {
$xsl_url = home_url('/?sitemaps-stylesheet=sitemap');
}
echo '<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="' . esc_url($xsl_url) . '" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" '.((!empty($siteseo->sitemap_settings['xml_sitemap_img_enable'])) ? 'xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"' : '').'>';
if($post_type == 'post' && self::$paged == 1){
echo "\t".'<url>
<loc>'.esc_url(home_url()).'</loc>
</url>';
}
foreach($posts as $post){
$image_xml = '';
if(!empty($siteseo->sitemap_settings['xml_sitemap_img_enable'])){
$images = self::get_page_images($post);
if(!empty($images)){
foreach($images as $image){
$image_xml .= "\t\t".'<image:image>'.PHP_EOL;
$image_xml .= "\t\t\t".'<image:loc>'.esc_url($image).'</image:loc>'.PHP_EOL;
$image_xml .= "\t\t".'</image:image>'.PHP_EOL;
}
}
}
echo "\t".'<url>
<loc>'.esc_url(urldecode(get_permalink($post->ID))).'</loc>
'.esc_xml($image_xml).'
<lastmod>'.esc_html(get_the_modified_date('c', $post->ID)).'</lastmod>
</url>';
}
echo '</urlset>';
exit;
}
static function generate_term_sitemap($taxonomy){
header('Content-Type: application/xml; charset=utf-8');
$offset = (2000*(self::$paged - 1));
if(get_option('permalink_structure')){
$xsl_url = home_url('/sitemaps.xsl');
} else {
$xsl_url = home_url('/?sitemaps-stylesheet=sitemap');
}
echo '<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="' . esc_url($xsl_url) . '" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
$terms = get_terms([
'taxonomy' => $taxonomy,
'hide_empty' => false,
'number' => 2000,
'offset' => $offset,
'hierarchical' => false,
'update_term_meta_cache' => false,
'meta_query' => [
[
'key' => '_siteseo_robots_index',
'compare' => 'NOT EXISTS'
]]
]);
foreach($terms as $term){
echo "\t". '<url>
<loc>'.esc_url(urldecode(get_term_link($term))).'</loc>
</url>';
}
echo '</urlset>';
exit;
}
static function generate_author_sitemap(){
header('Content-Type: application/xml; charset=utf-8');
if(get_option('permalink_structure')){
$xsl_url = home_url('/sitemaps.xsl');
} else {
$xsl_url = home_url('/?sitemaps-stylesheet=sitemap');
}
echo '<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="' . esc_url($xsl_url) . '" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
// Fetch all authors
$authors = get_users(
['capability' => ['publish_posts']]
);
foreach($authors as $author){
echo "\t".'<url>
<loc>'.esc_url(urldecode(get_author_posts_url($author->ID))).'</loc>
</url>';
}
echo '</urlset>';
exit;
}
static function html_sitemap($atts = []){
global $siteseo;
$atts = shortcode_atts(
[
'cpt' => '', // Default
],
$atts,
'siteseo_html_sitemap'
);
$disable_date = !empty($siteseo->sitemap_settings['xml_sitemap_html_date']);
$order_by = !empty($siteseo->sitemap_settings['xml_sitemap_html_orderby']) ? $siteseo->sitemap_settings['xml_sitemap_html_orderby'] : 'date';
$order = !empty($siteseo->sitemap_settings['xml_sitemap_html_order']) ? $siteseo->sitemap_settings['xml_sitemap_html_order'] : 'DESC';
$exclude_pages = array_map('trim', explode(',', $siteseo->sitemap_settings['xml_sitemap_html_exclude'] ?? ''));
$output = '';
if($order !== 'ASC' && $order !== 'DESC'){
$order = 'DESC';
}
$orderby_map = [
'Post Title' => 'title',
'Modified date' => 'modified',
'Post ID' => 'ID',
'Menu Order' => 'menu_order',
'date' => 'date', // Default
];
$orderby = $orderby_map[$order_by] ?? 'date';
$cpt_list = !empty($atts['cpt']) ? explode(',', $atts['cpt']) : [];
if(!empty($siteseo->sitemap_settings['xml_sitemap_post_types_list'])){
foreach($siteseo->sitemap_settings['xml_sitemap_post_types_list'] as $post_type => $settings){
if(!empty($settings['include']) && (empty($cpt_list) || in_array($post_type, $cpt_list))){
$output .= '<h2>'.esc_html(ucfirst($post_type)).'</h2>';
$args = [
'post_type' => $post_type,
'post_status' => 'publish',
'numberposts' => -1,
'orderby' => $orderby,
'order' => $order,
];
$posts = get_posts($args);
if(!empty($posts)){
$output .= '<ul>';
foreach($posts as $post){
if(in_array($post->ID, $exclude_pages)){
continue;
}
$post_title = get_the_title($post->ID) ?: $post->ID;
$output .= '<li><a href="'.esc_url(get_permalink($post->ID)).'">'.esc_html($post_title).'</a>';
if(!$disable_date){
$output .= '<span class="post-date"> - '.esc_html(get_the_modified_date('j F Y', $post->ID)).'</span>';
}
$output .= '</li>';
}
$output .= '</ul>';
}else{
$output .= '';
}
}
}
}
return $output;
}
static function sitemap_xsl(){
global $siteseo;
$pro_settings = isset($siteseo->pro) ? $siteseo->pro : '';
$title = __('XML Sitemap', 'siteseo');
$generated_by = __('Generated by SiteSEO', 'siteseo');
$sitemap_index_txt = __('This XML Sitemap Index file contains', 'siteseo');
$sitemap_count_txt = __('This XML Sitemap contains', 'siteseo');
$last_modified_txt = __('Last Modified', 'siteseo');
$index_sitemap_url = home_url('/sitemaps.xml');
$video_sitemap_enabled = !empty($pro_settings['toggle_state_video_sitemap']) && !empty($pro_settings['enable_video_sitemap']) ? true : false;
header('Content-Type: application/xml; charset=UTF-8');
echo '<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"';
if(!empty($pro_settings['toggle_state_google_news']) && !empty($pro_settings['google_news'])){
echo "\t" .'xmlns:news="https://www.google.com/schemas/sitemap-news/0.9/"';
}
if(!empty($pro_settings['toggle_state_video_sitemap']) && !empty($pro_settings['enable_video_sitemap'])){
echo "\t" .'xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"';
}
echo "\t" .'xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>'.esc_xml($title).'</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
* {
box-sizing: border-box;
}
body{
font-family: "Roboto", sans-serif;
background-color: #f0f2f5;
margin: 0;
padding: 0;
overflow-x: hidden;
}
header{
background: linear-gradient(135deg, #022448, #034f84);
padding: 20px;
color: #ffffff;
text-align: center;
width: 100%;
margin-bottom:15px;
}
header h1{
font-size: 32px;
margin: 0;
}
header p{
margin: 5px 0 0;
font-size: 16px;
text-decoration: underline;
}
header .siteseo-index-link a{
color: #ffffff;
text-decoration: none;
}
header .siteseo-index-link a:hover{
text-decoration: underline;
}
.siteseo-sitemap-container{
width: 60%;
padding: 20px;
background-color: #ffffff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
border-radius: 8px;
margin: 0 auto;
overflow: auto;
}
.siteseo-sitemap-container a{
color:#007bff;
text-decoration: none;
}
table{
width: 100%;
border-collapse: collapse;
}
table thead tr{
background-color: #034f84;
color: #ffffff;
}
table th, table td{
padding: 10px;
text-align: left;
border: 1px solid #ddd;
}
table tbody tr:nth-child(even){
background-color: #f9f9f9;
}
.siteseo-video-thumbnail{
max-width: 160px;
max-height: 120px;
border-radius: 4px;
}
.siteseo-video-info{
margin-left: 15px;
}
.siteseo-video-container{
display: flex;
align-items: center;
margin: 10px 0;
}
.siteseo-video-title{
font-weight: bold;
margin-bottom: 5px;
}
.siteseo-video-description{
color: #555;
font-size: 14px;
margin-bottom: 5px;
}
.siteseo-video-meta{
font-size: 13px;
color: #777;
}
.siteseo-video-url{
word-break: break-all;
font-size: 13px;
color: #007bff;
}
</style>
</head>
<body>
<header>
<h1>'.esc_xml($title).'</h1>
<span>'.esc_xml($generated_by).'</span>
<xsl:if test="count(sitemap:sitemapindex/sitemap:sitemap) > 0">
<div class="siteseo-description" style="text-align:center;">'.esc_xml($sitemap_index_txt).' <xsl:value-of select="count(sitemap:sitemapindex/sitemap:sitemap)"/> sitemaps</div>
</xsl:if>
<xsl:if test="count(sitemap:sitemapindex/sitemap:sitemap) < 1">
<div class="siteseo-description" style="text-align:center;">'.esc_xml($sitemap_count_txt).' <xsl:value-of select="count(sitemap:urlset/sitemap:url)"/> URLs</div>
</xsl:if>
</header>
<div class="siteseo-sitemap-container">
<xsl:if test="count(sitemap:sitemapindex/sitemap:sitemap) < 1">
<a href="'.esc_url($index_sitemap_url).'">Index Sitemap</a>
</xsl:if>
<table>
<xsl:if test="count(sitemap:sitemapindex/sitemap:sitemap) > 0">
<thead>
<tr><th>URL</th></tr>
</thead>
<tbody>
<xsl:for-each select="sitemap:sitemapindex/sitemap:sitemap">
<tr>
<td><a href="{sitemap:loc}"><xsl:value-of select="sitemap:loc"/></a></td>
</tr>
</xsl:for-each>
</tbody>
</xsl:if>
<xsl:if test="count(sitemap:sitemapindex/sitemap:sitemap) < 1">';
if($video_sitemap_enabled && class_exists('\SiteSEOPro\VideoSitemap') && method_exists('\SiteSEOPro\VideoSitemap', 'render_video_xsl')){
echo'<xsl:if test="sitemap:urlset/sitemap:url/video:video">'
. \SiteSEOPro\VideoSitemap::render_video_xsl() .
'</xsl:if>
<xsl:if test="not(sitemap:urlset/sitemap:url/video:video)">
<thead>
<tr>
<th>URL</th>
<th>'.esc_xml($last_modified_txt).'</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="sitemap:urlset/sitemap:url">
<tr>
<td><a href="{sitemap:loc}"><xsl:value-of select="sitemap:loc"/></a></td>
<td><xsl:value-of select="sitemap:lastmod"/></td>
</tr>
</xsl:for-each>
</tbody>
</xsl:if>';
} else {
echo'<xsl:if test="count(sitemap:sitemapindex/sitemap:sitemap) < 1">
<thead>
<tr>
<th>URL</th>
<th>'.esc_xml($last_modified_txt).'</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="sitemap:urlset/sitemap:url">
<tr>
<td><a href="{sitemap:loc}"><xsl:value-of select="sitemap:loc"/></a></td>
<td><xsl:value-of select="sitemap:lastmod"/></td>
</tr>
</xsl:for-each>
</tbody>
</xsl:if>';
}
echo'</xsl:if>
</table>
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>';
}
static function get_page_images($post){
$images = [];
$thumb = get_the_post_thumbnail_url($post->ID);
if(!empty($thumb)){
$images[] = $thumb;
}
if(!class_exists('DOMDocument') || empty($post->post_content)){
return $images;
}
libxml_use_internal_errors(true);
$dom = new \DOMDocument();
$dom->loadHTML('<?xml encoding="utf-8" ?>' . $post->post_content);
$dom->preserveWhiteSpace = false;
libxml_clear_errors();
$img_tags = $dom->getElementsByTagName('img');
if(empty($img_tags)){
return;
}
foreach($img_tags as $img_tag){
$url = $img_tag->getAttribute('src');
if(empty($url)){
continue;
}
$url = sanitize_url($url);
// The Image has some different URL which means it does not belongs to our site.
if(strpos($url, untrailingslashit(home_url())) === FALSE){
continue;
}
$images[] = $url;
}
return $images;
}
static function maybe_redirect(){
global $wp;
if(empty($wp) || empty($wp->request)){
return;
}
$redirects = ['sitemap.xml', 'wp-sitemap.xml', 'sitemap_index.xml'];
if(in_array($wp->request, $redirects)){
wp_safe_redirect(home_url('sitemaps.xml'), 301);
die();
}
}
}